//学习 建造者模式

#include <iostream>
#include <string>
#include <memory>
using namespace std;

//基本的电脑抽象类
class Computer
{
public:
    void setBoard(const string &board)
    {
        _board = board;
    }
    void setDisplay(const string &display)
    {
        _display = display;
    }

    virtual void setOS() = 0;

    void showParameter()
    {
        cout << "\nComputer Parameter" << endl;
        cout << "\tBoard: " << _board << endl;
        cout << "\tDisplay: " << _display << endl;
        cout << "\tOS: " << _OS << endl;
        cout << endl;
    }

protected:
    string _board;  //主板
    string _display;    //显示器
    string _OS; //操作系统   
};

//Windows
class Windows : public Computer
{
public:
    void setOS()
    {
        //植入鸿蒙系统
        _OS = "Harmony 4.0";
    }
};

//抽象的建造者类
class Build
{
public:
    virtual void buildBoard(const string &board) = 0;
    virtual void buildDisplay(const string &display) = 0;
    virtual void buildOS() = 0;
    virtual shared_ptr<Computer> bulidComputer() = 0;
};

//具体的Windows建造类
class WinBuild : public Build
{
public:
    WinBuild()
        :_computer(new Windows())
    {}

    void buildBoard(const string &board)
    {
        _computer->setBoard(board);
    }

    void buildDisplay(const string &display)
    {
        _computer->setDisplay(display);
    }

    void buildOS()
    {
        _computer->setOS();
    }

    shared_ptr<Computer> bulidComputer()
    {
        return _computer;
    }

private:
    shared_ptr<Computer> _computer;
};

//指挥者类，零部件如何组装取决于指挥者
class Directer
{
public:
    Directer(Build *build)
        :_builder(build)
    {}

    void Construct(const string &board, const string &display)
    {
        _builder->buildBoard(board);
        _builder->buildDisplay(display);
        _builder->buildOS();
    }

private:
    shared_ptr<Build> _builder;
};

int main()
{
    Build *bulider = new WinBuild();
    unique_ptr<Directer> directer(new Directer(bulider));
    directer->Construct("华硕ROG MAXIMUS XIII EXTREME GLACIAL", "华为MateView GT 34英寸 Sound版");
    shared_ptr<Computer> computer = bulider->bulidComputer();
    computer->showParameter();
    return 0;
}